
/**
 * Baijiahulian.com Inc. Copyright (c) 2014-2016 All Rights Reserved.
 */

package org.xeustechnologies.jcl;

import lombok.extern.slf4j.Slf4j;

/**
 * @say little Boy, don't be sad.
 * @name Rezar
 * @time Sep 7, 2016
 * @Desc this guy is too lazy, nothing left.
 */
@Slf4j
public class CustomizeClassLoader extends ClassLoader implements ResourceClassLoader<CustomizeClassLoader> {

    private ClassLoader parentLoader;

    public CustomizeClassLoader() {

    }

    public CustomizeClassLoader(ClassLoader loader) {
        super(loader);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
     */
    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        log.info("attempt to load class:{} and resolve is : {} ", name, resolve);
        if (this.parentLoader != null) {
            Class<?> loadClass = this.parentLoader.loadClass(name);
            if (resolve && loadClass != null) {
                this.resolveClass(loadClass);
            }
            return loadClass;
        }
        return super.loadClass(name, resolve);
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        log.info("attempt to load class:{}  ", name);
        return ClassPathClassLoader.newInstance().loadClass(name, false);
    }

    public Class<?> loadClassWithResource(String name, boolean resolve, byte[] resource) throws ClassNotFoundException {
        log.info("className is : {}" , name);
        Class<?> clazz = this.findLoadedClass(name);
        if (clazz != null) {
            log.info("class:{} has already load , and will return it direct", name);
            return clazz;
        }
        try {
            clazz = this.defineClass(name, resource, 0, resource.length);
            if (resolve) {
                super.resolveClass(clazz);
            }
            return clazz;
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("error : {} ", e.getMessage());
        }
        return ClassPathClassLoader.newInstance().loadClass(name, false);
    }

    public Class<?> loadClassWithResource(String name, byte[] resource) throws ClassNotFoundException {
        return this.loadClassWithResource(name, false, resource);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */

    @Override
    public String toString() {
        return "CustomizeClassLoader [Hello Workd!] " + this.hashCode();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.xeustechnologies.jcl.ResourceClassLoader#setParentLoader(java.lang.ClassLoader)
     */

    public void setParentLoader(ClassLoader loader) {
        if (loader != null && this.parentLoader == null) {
            this.parentLoader = loader;
        }
    }

}
